package org.behrang.macbeans.tab.coda;

import org.behrang.macbeans.tab.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import org.netbeans.swing.tabcontrol.plaf.AbstractTabCellRenderer;
import org.netbeans.swing.tabcontrol.plaf.TabPainter;

/**
 *
 * @author Behrang Saeedzadeh <behrangsa@gmail.com>
 */
public class CodaEditorTabCellRenderer extends MacBeansTabCellRenderer {

    private static final TabPainter PAINTER = new CodaEditorTabPainter();

    public CodaEditorTabCellRenderer() {
        super(PAINTER, PAINTER, PAINTER, new Dimension(14, 0));
    }

    @Override
    public Dimension getPadding() {
        Dimension d = super.getPadding();
        d.width = isShowCloseButton() && !Boolean.getBoolean("nb.tabs.suppressCloseButton") ? 26 : 18;
        return d;
    }

    private static class CodaEditorTabPainter implements TabPainter {

        public static final Color TOP = new Color(64, 64, 64);
        public static final Color SIDE = new Color(170, 170, 170);
        public static final Color BG_TOP = new Color(237, 237, 237);
        public static final Color BG_BOTTOM = new Color(210, 210, 210);
        public static final Color SBG_TOP = new Color(188, 188, 188);
        public static final Color SBG_BOTTOM = new Color(229, 229, 229);
        public static final Color ABG_TOP = new Color(218, 218, 218);
        public static final Color ABG_BOTTOM = new Color(181, 181, 181);

        public void getCloseButtonRectangle(JComponent jc, Rectangle rect,
                Rectangle bounds) {
            boolean rightClip = ((CodaEditorTabCellRenderer) jc).isClipRight();
            boolean leftClip = ((CodaEditorTabCellRenderer) jc).isClipLeft();
            boolean notSupported = !((AbstractTabCellRenderer) jc).isShowCloseButton();
            if (leftClip || rightClip || notSupported) {
                rect.x = -100;
                rect.y = -100;
                rect.width = 0;
                rect.height = 0;
            } else {
                URL iconPath = findIconPath((CodaEditorTabCellRenderer) jc);
                Icon icon = new ImageIcon(iconPath);
                int iconWidth = icon.getIconWidth();
                int iconHeight = icon.getIconHeight();
                rect.x = bounds.x + bounds.width - iconWidth - 2;
                rect.y = bounds.y + (Math.max(0, bounds.height / 2 - iconHeight / 2));
                rect.width = iconWidth;
                rect.height = iconHeight;
            }
        }

        private URL findIconPath(CodaEditorTabCellRenderer renderer ) {
            
            URL url = getClass().getResource("resources/tab_close.png");
            
            if (renderer.inCloseButton() && renderer.isPressed() ) {
                url = getClass().getResource("resources/tab_close_pressed.png");
            } else if( renderer.inCloseButton() ) {
                url = getClass().getResource("resources/tab_close_rollover.png");
            } else {
                url = getClass().getResource("resources/tab_close.png");
            }
            
            return url;            
        }

        private void paintCloseButton(Graphics g, JComponent c) {
            if (((AbstractTabCellRenderer) c).isShowCloseButton()) {

                Rectangle r = new Rectangle(0, 0, c.getWidth(), c.getHeight());
                Rectangle cbRect = new Rectangle();
                getCloseButtonRectangle((JComponent) c, cbRect, r);

                //paint close button
                URL iconPath = findIconPath((CodaEditorTabCellRenderer) c);
                Icon icon = new  ImageIcon(iconPath);
                icon.paintIcon(c, g, cbRect.x, cbRect.y);
            }
        }

        public Polygon getInteriorPolygon(Component renderer) {
            return new Polygon(
                    new int[]{0, renderer.getWidth(), renderer.getWidth(), 0},
                    new int[]{0, 0, renderer.getHeight(), renderer.getHeight()}, 4);
        }

        public void paintInterior(Graphics gr, Component renderer) {
            if (((CodaEditorTabCellRenderer) renderer).isSelected()) {
                paintSelectedInterior(gr, renderer);
            } else {
                paintNormalInterior(gr, renderer, ((CodaEditorTabCellRenderer) renderer).isArmed());
            }
        }

        public void paintNormalInterior(Graphics gr, Component renderer, boolean isArmed) {
            Rectangle bounds = renderer.getBounds();
            int x = 0, y = 0, width = bounds.width, height = bounds.height;
            Graphics2D g = (Graphics2D) gr;
            GradientPaint gp = null;
            if (isArmed) {
                gp = new GradientPaint(x, y, ABG_TOP, x, y + height, ABG_BOTTOM);
            } else {
                gp = new GradientPaint(x, y, BG_TOP, x, y + height, BG_BOTTOM);
            }
            Rectangle2D bg = new Rectangle2D.Double(x + 1, y + 1, width - 1, height - 1);
            g.setPaint(gp);
            g.fill(bg);
        }

        private void paintSelectedInterior(Graphics gr, Component renderer) {
            Rectangle bounds = renderer.getBounds();
            int x = 0, y = 0, width = bounds.width, height = bounds.height;
            Graphics2D g = (Graphics2D) gr;
            GradientPaint gp = new GradientPaint(x, y, SBG_TOP, x, y + height, SBG_BOTTOM);
            Rectangle2D bg = new Rectangle2D.Double(x + 1, y + 1, width - 1, height - 1);
            g.setPaint(gp);
            g.fill(bg);
        }

        public boolean supportsCloseButton(JComponent c) {
            return true;
        }

        public Insets getBorderInsets(Component c) {
            return new Insets(1, 1, 1, 1);
        }

        public boolean isBorderOpaque() {
            return false;
        }

        public void paintBorder(Component renderer, Graphics g, int x, int y, int width, int height) {

            paintCloseButton(g, (JComponent) renderer);

            // top border            
            g.setColor(TOP);
            g.drawLine(x, y, x + width, y);

            g.setColor(SIDE);

            // right border
            g.drawLine(x, y + 1, x, y + height);

            // bottom border
            g.drawLine(x, y + height - 1, x + width, y + height - 1);
        }
    }
}
